package org.larkdoc.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.larkdoc.config.ReadConfig;
import org.larkdoc.constant.ViewConts;
import org.larkdoc.model.entity.UserInfo;
import org.larkdoc.model.vo.RespBaseVO;
import org.larkdoc.service.UserService;
import org.larkdoc.util.AuthUtil;
import org.larkdoc.util.EncryUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 登录信息控制类
 * 
 * @author  zhangpeijun[zhangpeijun1024@qq.com]
 * @version  [v1.0.1, 2017年10月17日]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
@Controller
public class LoginController {
    
    private final static Logger LOG = LoggerFactory.getLogger(LoginController.class);
    
    @Autowired
    UserService                 userService;
    
    @Autowired
    ReadConfig                  readConfig;
    
    @RequestMapping(value = "/login_pre")
    public String loginPre() {
        return "login";
    }
    
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String login(HttpServletRequest request, UserInfo user, Model model) {
        String msg = "";
        if (null != user && StringUtils.isNotBlank(user.getAccount()) && StringUtils.isNotBlank(user.getPassword())) {
            // TODO 帐号验证，密码验证等
            String account = user.getAccount().trim();
            String password = EncryUtil.md5Encry(user.getPassword().trim(), account + readConfig.getPubSalt());
            UsernamePasswordToken token = new UsernamePasswordToken(account, password);
            token.setRememberMe(false);
            Subject subject = SecurityUtils.getSubject();
            try {
                if (!subject.isAuthenticated()) {
                    subject.login(token);
                    HttpSession session = request.getSession();
                    session.setAttribute("user", account);
                } else {
                    //                    respVo.setRetMsg("会话已建立,无需重复登录。");
                }
                return "redirect:/doc/page";
            } catch (
                UnknownAccountException | IncorrectCredentialsException e) {
                LOG.info("login UnknownAccountException or IncorrectCredentialsException :", e);
                LOG.warn("login expetion", e);
                msg = "登录验证失败。";
            } catch (LockedAccountException e) {
                LOG.info("login user locked. account = ", account);
                msg = "用户已锁定。";
            } catch (AuthenticationException e) {
                LOG.info("login AuthenticationException: {}", e);
                msg = "登录验证失败。";
            }
        } else {
            msg = "请求参数为空。";
        }
        model.addAttribute("message", msg);
        return "/error";
    }
    
    @RequestMapping(value = "/loginAjax", method = RequestMethod.POST)
    @ResponseBody
    public RespBaseVO loginJson(HttpServletRequest request, UserInfo user) {
        RespBaseVO respVo = new RespBaseVO();
        if (null != user && StringUtils.isNotBlank(user.getAccount()) && StringUtils.isNotBlank(user.getPassword())) {
            // TODO 帐号验证，密码验证等
            String account = user.getAccount().trim();
            String password = EncryUtil.md5Encry(user.getPassword().trim(), account + readConfig.getPubSalt());
            UsernamePasswordToken token = new UsernamePasswordToken(account, password);
            token.setRememberMe(false);
            Subject subject = SecurityUtils.getSubject();
            try {
                if (!subject.isAuthenticated()) {
                    subject.login(token);
                    HttpSession session = request.getSession();
                    session.setAttribute("user", account);
                } else {
                    respVo.setRetMsg("会话已建立,无需重复登录。");
                }
            } catch (
                UnknownAccountException | IncorrectCredentialsException e) {
                LOG.info("login UnknownAccountException or IncorrectCredentialsException :", e);
                LOG.warn("login expetion", e);
                respVo.setRetCode(ViewConts.Code.USER_ERROR);
                respVo.setRetMsg(ViewConts.Msg.USER_ERROR);
            } catch (LockedAccountException e) {
                LOG.info("login user locked. account = ", account);
                respVo.setRetCode(ViewConts.Code.USER_LOCKED);
                respVo.setRetMsg(ViewConts.Msg.USER_LOCKED);
            } catch (AuthenticationException e) {
                LOG.info("login AuthenticationException: {}", e);
                respVo.setRetCode(ViewConts.Code.USER_ERROR);
                respVo.setRetMsg(ViewConts.Msg.USER_ERROR);
            }
        } else {
            respVo.setRetCode(ViewConts.Code.PARAM_ERROR);
            respVo.setRetMsg(ViewConts.Msg.PARAM_ERROR);
        }
        return respVo;
    }
    
    @RequestMapping(value = "/logout")
    public String logout(UserInfo user) {
        SecurityUtils.getSubject().logout();
        return "redirect:/";
    }
    
    @RequestMapping(value = "/isLogin")
    @ResponseBody
    public RespBaseVO isLogin() {
        RespBaseVO respVo = new RespBaseVO();
        Subject subject = SecurityUtils.getSubject();
        if (null != subject && subject.isAuthenticated()) {
            respVo.setRetVal(true);
            respVo.setRetMsg(AuthUtil.getAccount());
        } else {
            respVo.setRetVal(false);
            respVo.setRetMsg("请登录");
        }
        return respVo;
    }
}
